package com.movie.service.impl;

import com.movie.dto.PermissionDTO;
import com.movie.dto.RoleDTO;
import com.movie.entity.Permission;
import com.movie.entity.Role;
import com.movie.entity.SysUser;
import com.movie.entity.User;
import com.movie.repository.PermissionRepository;
import com.movie.repository.RoleRepository;
import com.movie.repository.SystemUserRepository;
import com.movie.repository.UserRepository;
import com.movie.service.PermissionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class PermissionServiceImpl implements PermissionService {
    
    private final RoleRepository roleRepository;
    private final PermissionRepository permissionRepository;
    private final SystemUserRepository userRepository;
    
    @Override
    public Page<RoleDTO> getRoleList(Pageable pageable) {
        log.info("获取角色列表");
        Page<Role> rolePage = roleRepository.findAll(pageable);
        return rolePage.map(this::convertRoleToDTO);
    }
    
    @Override
    public RoleDTO getRoleDetail(Long roleId) {
        log.info("获取角色详情: {}", roleId);
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new RuntimeException("角色不存在"));
        return convertRoleToDTO(role);
    }
    
    @Override
    public RoleDTO createRole(RoleDTO roleDTO) {
        log.info("创建角色: {}", roleDTO.getName());
        Role role = convertRoleToEntity(roleDTO);
        Role saved = roleRepository.save(role);
        return convertRoleToDTO(saved);
    }
    
    @Override
    public RoleDTO updateRole(Long roleId, RoleDTO roleDTO) {
        log.info("更新角色: {}", roleId);
        Role existingRole = roleRepository.findById(roleId)
                .orElseThrow(() -> new RuntimeException("角色不存在"));
        
        // 只更新基本信息，不更新权限关系（权限通过单独的方法更新）
        existingRole.setName(roleDTO.getName());
        existingRole.setDescription(roleDTO.getDescription());
        Role updated = roleRepository.save(existingRole);
        return convertRoleToDTO(updated);
    }
    
    @Override
    public void deleteRole(Long roleId) {
        log.info("删除角色: {}", roleId);
        if (!roleRepository.existsById(roleId)) {
            throw new RuntimeException("角色不存在");
        }
        roleRepository.deleteById(roleId);
    }
    
    @Override
    public List<PermissionDTO> getPermissionList() {
        log.info("获取权限列表");
        List<Permission> permissions = permissionRepository.findAll();
        return permissions.stream()
                .map(this::convertPermissionToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public void updateRolePermissions(Long roleId, List<Long> permissionIds) {
        log.info("更新角色权限: {}, permissions: {}", roleId, permissionIds);
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new RuntimeException("角色不存在"));
        
        List<Permission> permissions = permissionRepository.findAllById(permissionIds);
        role.setPermissions(permissions);
        roleRepository.save(role);
    }
    
    @Override
    public List<RoleDTO> getUserRoles(Long userId) {
        log.info("获取用户角色: {}", userId);
        SysUser user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        return user.getRoles().stream()
                .map(this::convertRoleToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public void assignUserRoles(Long userId, List<Long> roleIds) {
        log.info("分配用户角色: {}, roles: {}", userId, roleIds);
        SysUser user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        List<Role> roles = roleRepository.findAllById(roleIds);
        user.setRoles(roles);
        userRepository.save(user);
    }
    
    private RoleDTO convertRoleToDTO(Role role) {
        RoleDTO dto = new RoleDTO();
        BeanUtils.copyProperties(role, dto);
        
        // 统计用户数量
        Long userCount = roleRepository.countUsersByRoleId(role.getId());
        dto.setUserCount(userCount != null ? userCount.intValue() : 0);
        
        // 转换权限列表
        if (role.getPermissions() != null) {
            List<PermissionDTO> permissionDTOs = role.getPermissions().stream()
                    .map(this::convertPermissionToDTO)
                    .collect(Collectors.toList());
            dto.setPermissions(permissionDTOs);
        }
        
        return dto;
    }
    
    private Role convertRoleToEntity(RoleDTO dto) {
        Role role = new Role();
        BeanUtils.copyProperties(dto, role);
        
        // 注意：从DTO创建实体时，权限列表需要单独处理
        // 通常在创建角色时不会直接设置权限，而是通过单独的权限分配方法
        role.setPermissions(null);
        
        return role;
    }
    
    private PermissionDTO convertPermissionToDTO(Permission permission) {
        PermissionDTO dto = new PermissionDTO();
        BeanUtils.copyProperties(permission, dto);
        return dto;
    }
}